package cn.youqu.happy.module.youqu.service.userBlack;

import cn.youqu.happy.framework.common.pojo.PageResult;
import cn.youqu.happy.module.member.dal.dataobject.user.MemberUserDO;
import cn.youqu.happy.module.member.service.user.MemberUserService;
import cn.youqu.happy.module.youqu.controller.admin.userBlack.vo.UserBlackCreateReqVO;
import cn.youqu.happy.module.youqu.controller.admin.userBlack.vo.UserBlackExportReqVO;
import cn.youqu.happy.module.youqu.controller.admin.userBlack.vo.UserBlackPageReqVO;
import cn.youqu.happy.module.youqu.controller.admin.userBlack.vo.UserBlackUpdateReqVO;
import cn.youqu.happy.module.youqu.controller.app.userBlack.vo.AppUserBlackJoinReqVO;
import cn.youqu.happy.module.youqu.controller.app.userBlack.vo.AppUserBlackUpdateReqVO;
import cn.youqu.happy.module.youqu.convert.userBlack.UserBlackConvert;
import cn.youqu.happy.module.youqu.dal.dataobject.userBlack.UserBlackDO;
import cn.youqu.happy.module.youqu.dal.mysql.userBlack.UserBlackMapper;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import static cn.youqu.happy.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.youqu.happy.module.member.enums.ErrorCodeConstants.USER_NOT_EXISTS;
import static cn.youqu.happy.module.youqu.enums.ErrorCodeConstants.*;

/**
 * 用户黑名单 Service 实现类
 *
 * @author 王其岩 20112001045
 */
@Service
@Validated
public class UserBlackServiceImpl implements UserBlackService {

    @Resource
    private UserBlackMapper userBlackMapper;

    @Resource
    @Lazy
    private MemberUserService memberUserService;

    @Override
    public Integer createUserBlack(UserBlackCreateReqVO createReqVO) {
        // 插入
        UserBlackDO userBlack = UserBlackConvert.INSTANCE.convert(createReqVO);
        userBlackMapper.insert(userBlack);
        // 返回
        return userBlack.getId();
    }

    @Override
    public Integer joinUserBlack(AppUserBlackJoinReqVO joinReqVO, Long uid) {
        MemberUserDO user = this.memberUserService.getUser(joinReqVO.getTargetId());
        if (user == null) {
            throw exception(USER_NOT_EXISTS);
        }
        //判断是否是自己
        if (user.getId().equals(uid)) {
            throw exception(USER_BLACK_CAN_NOT_JOIN_YOURSELF);
        }
        //判断是否已加入
        if (this.validateInUserBlack(joinReqVO.getTargetId(), uid)) {
            throw exception(USER_BLACK_ALREADY_JOIN);
        }
        UserBlackDO userBlack = UserBlackConvert.INSTANCE.convert(joinReqVO);
        //设置默认值
        userBlack.setUid(uid);
        // 插入
        userBlackMapper.insert(userBlack);
        // 返回
        return userBlack.getId();
    }

    @Override
    public boolean validateInUserBlack(Long targetId, Long uid) {
        UserBlackDO userBlackDO = userBlackMapper.findOneByUidAndTargetId(uid, targetId);
        return userBlackDO != null;
    }

    @Override
    public UserBlackDO getUserBlack(Long targetId, Long uid) {
        userBlackMapper.findOneByUidAndTargetId(uid, targetId);
        return userBlackMapper.findOneByUidAndTargetId(uid, targetId);
    }

    @Override
    public void updateUserBlack(UserBlackUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateUserBlackExists(updateReqVO.getId());
        // 更新
        UserBlackDO updateObj = UserBlackConvert.INSTANCE.convert(updateReqVO);
        userBlackMapper.updateById(updateObj);
    }

    @Override
    public void deleteUserBlack(Integer id) {
        // 校验存在
        this.validateUserBlackExists(id);
        // 删除
        userBlackMapper.deleteById(id);
    }

    private void validateUserBlackExists(Integer id) {
        if (userBlackMapper.selectById(id) == null) {
            throw exception(USER_BLACK_NOT_EXISTS);
        }
    }

    private void validateUserBlackExists(Integer id, Long uid) {
        if (userBlackMapper.findByIdAndUid(id, uid) == null) {
            throw exception(USER_BLACK_NOT_EXISTS);
        }
    }

    private List<UserBlackDO> filterUserOwnUserBlack(List<UserBlackDO> userBlackDOS, Long uid) {
        return userBlackDOS.stream().filter(item -> uid.equals(item.getUid())).collect(Collectors.toList());
    }

    @Override
    public UserBlackDO getUserBlack(Integer id) {
        return userBlackMapper.selectById(id);
    }

    @Override
    public List<UserBlackDO> getUserBlackList(Collection<Integer> ids) {
        return userBlackMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<UserBlackDO> getUserBlackPage(UserBlackPageReqVO pageReqVO) {
        return userBlackMapper.selectPage(pageReqVO);
    }

    @Override
    public List<UserBlackDO> getUserBlackList(UserBlackExportReqVO exportReqVO) {
        return userBlackMapper.selectList(exportReqVO);
    }

    @Override
    public void deleteUserBlack(Integer id, Long loginUserId) {
        this.validateUserBlackExists(id, loginUserId);
        // 删除
        userBlackMapper.deleteById(id);
    }


    @Override
    public PageResult<UserBlackDO> getUserBlackPage(UserBlackPageReqVO pageVO, Long loginUserId) {
        PageResult<UserBlackDO> userBlackDOPageResult = userBlackMapper.selectPage(pageVO);
        List<UserBlackDO> list = userBlackDOPageResult.getList();
        userBlackDOPageResult.setList(filterUserOwnUserBlack(list, loginUserId));
        userBlackDOPageResult.setTotal((long) list.size());
        return userBlackDOPageResult;
    }

    @Override
    public List<UserBlackDO> getUserBlackList(Collection<Integer> ids, Long loginUserId) {
        List<UserBlackDO> userBlackDOS = userBlackMapper.selectBatchIds(ids);
        return filterUserOwnUserBlack(userBlackDOS, loginUserId);
    }

    @Override
    public List<UserBlackDO> getUserBlackList(Long targetId) {
        return userBlackMapper.findAllByTargetId(targetId);
    }

    @Override
    public UserBlackDO getUserBlack(Integer id, Long loginUserId) {
        return userBlackMapper.findByIdAndUid(id, loginUserId);
    }

    @Override
    public void updateUserBlack(AppUserBlackUpdateReqVO updateReqVO, Long loginUserId) {
        this.validateUserBlackExists(updateReqVO.getId(), loginUserId);
        userBlackMapper.updateById(UserBlackConvert.INSTANCE.convert(updateReqVO));
    }

}
